function checkTingPai(seatData, begin, end) {
	for (var i = begin; i < end; ++i) {
		//如果这牌已经在和了，就不用检查了
		if (seatData.tingMap[i] != null) {
			continue;
		}
		//将牌加入到计数中
		var old = seatData.countMap[i];
		if (old == null) {
			old = 0;
			seatData.countMap[i] = 1;
		} else {
			seatData.countMap[i]++;
		}

		seatData.holds.push(i);
		//逐个判定手上的牌
		var ret = checkCanHu(seatData);
		if (ret) {
			//平胡 0番
			seatData.tingMap[i] = {
				pattern: "normal",
				fan: 0
			};
		}

		//搞完以后，撤消刚刚加的牌
		seatData.countMap[i] = old;
		seatData.holds.pop();
	}
}

var kanzi = [];
var record = false;
function debugRecord(pai) {
	if (record) {
		kanzi.push(pai);
	}
}

function matchSingle(seatData, selected) {
	//分开匹配 A-2,A-1,A
	var matched = true;
	var v = selected % 9;
	if (v < 2) {
		matched = false;
	} else {
		for (var i = 0; i < 3; ++i) {
			var t = selected - 2 + i;
			var cc = seatData.countMap[t];
			if (cc == null) {
				matched = false;
				break;
			}
			if (cc == 0) {
				matched = false;
				break;
			}
		}
	}


	//匹配成功，扣除相应数值
	if (matched) {
		seatData.countMap[selected - 2]--;
		seatData.countMap[selected - 1]--;
		seatData.countMap[selected]--;
		var ret = checkSingle(seatData);
		seatData.countMap[selected - 2]++;
		seatData.countMap[selected - 1]++;
		seatData.countMap[selected]++;
		if (ret == true) {
			debugRecord(selected - 2);
			debugRecord(selected - 1);
			debugRecord(selected);
			return true;
		}
	}

	//分开匹配 A-1,A,A + 1
	matched = true;
	if (v < 1 || v > 7) {
		matched = false;
	} else {
		for (var i = 0; i < 3; ++i) {
			var t = selected - 1 + i;
			var cc = seatData.countMap[t];
			if (cc == null) {
				matched = false;
				break;
			}
			if (cc == 0) {
				matched = false;
				break;
			}
		}
	}

	//匹配成功，扣除相应数值
	if (matched) {
		seatData.countMap[selected - 1]--;
		seatData.countMap[selected]--;
		seatData.countMap[selected + 1]--;
		var ret = checkSingle(seatData);
		seatData.countMap[selected - 1]++;
		seatData.countMap[selected]++;
		seatData.countMap[selected + 1]++;
		if (ret == true) {
			debugRecord(selected - 1);
			debugRecord(selected);
			debugRecord(selected + 1);
			return true;
		}
	}


	//分开匹配 A,A+1,A + 2
	matched = true;
	if (v > 6) {
		matched = false;
	} else {
		for (var i = 0; i < 3; ++i) {
			var t = selected + i;
			var cc = seatData.countMap[t];
			if (cc == null) {
				matched = false;
				break;
			}
			if (cc == 0) {
				matched = false;
				break;
			}
		}
	}

	//匹配成功，扣除相应数值
	if (matched) {
		seatData.countMap[selected]--;
		seatData.countMap[selected + 1]--;
		seatData.countMap[selected + 2]--;
		var ret = checkSingle(seatData);
		seatData.countMap[selected]++;
		seatData.countMap[selected + 1]++;
		seatData.countMap[selected + 2]++;
		if (ret == true) {
			debugRecord(selected);
			debugRecord(selected + 1);
			debugRecord(selected + 2);
			return true;
		}
	}
	return false;
}

function checkSingle(seatData) {
	var holds = seatData.holds;
	var selected = -1;
	var c = 0;

	for (var i = 0; i < holds.length; ++i) {
		var pai = holds[i];
		c = seatData.countMap[pai];
		if (c != 0) {
			selected = pai;
			break;
		}
	}
	//如果没有找到剩余牌，则表示匹配成功了
	if (selected == -1) {
		return true;
	}
	// console.log('check single', c, selected, options);

	//否则，进行匹配
	if (c == 3) {
		//直接作为一坎
		seatData.countMap[selected] = 0;
		debugRecord(selected);
		debugRecord(selected);
		debugRecord(selected);
		var ret = checkSingle(seatData);
		//立即恢复对数据的修改
		seatData.countMap[selected] = c;
		if (ret == true) {
			return true;
		}
	} else if (c == 4) {
		//直接作为一坎
		seatData.countMap[selected] = 1;
		debugRecord(selected);
		debugRecord(selected);
		debugRecord(selected);
		var ret = checkSingle(seatData);
		//立即恢复对数据的修改
		seatData.countMap[selected] = c;
		//如果作为一坎能够把牌匹配完，直接返回TRUE。
		if (ret == true) {
			return true;
		}
	}

	// 按单牌处理
	return matchSingle(seatData, selected);
}

function checkCanHu(seatData) {
	for (var k in seatData.countMap) {
		k = parseInt(k);
		var c = seatData.countMap[k];
		if (c < 2) {
			continue;
		}
		//如果当前牌大于等于２，则将它选为将牌
		seatData.countMap[k] -= 2;
		//逐个判定剩下的牌是否满足　３Ｎ规则,一个牌会有以下几种情况
		//1、0张，则不做任何处理
		//2、2张，则只可能是与其它牌形成匹配关系
		//3、3张，则可能是单张形成 A-2,A-1,A  A-1,A,A+1  A,A+1,A+2，也可能是直接成为一坎
		//4、4张，则只可能是一坎+单张
		kanzi = [];
		var ret;
		ret = checkSingle(seatData);
		seatData.countMap[k] += 2;
		if (ret) {
			//kanzi.push(k);
			//kanzi.push(k);
			//console.log(kanzi);
			return true;
		}
	}

}

// match顺子
// 记录顺子
let keArr = [];
const matchShun = function (seatData, pai) {
	const { holds, countMap } = seatData;
	let result = {
		shunStrArr: [],
		matchShun: false,
	};
	var selected = pai;
	// 分开匹配 A-2,A-1,A
	var matched = true;
	var v = selected % 9;
	if (v < 2) {
		matched = false;
	} else {
		for (var i = 0; i < 3; ++i) {
			var t = selected - 2 + i;
			var cc = countMap[t];
			if (cc == null) {
				matched = false;
				break;
			}
			if (cc == 0) {
				matched = false;
				break;
			}
		}
	}

	// 匹配成功，扣除相应数值，记录
	if (matched) {
		result.shunStrArr.push(`${selected - 2},${selected - 1},${selected}`);
		result.matchShun = true;
		// countMap[selected - 2]--;
		// countMap[selected - 1]--;
		// countMap[selected]--;
		// var ret = checkSingle(seatData);
		// countMap[selected - 2]++;
		// countMap[selected - 1]++;
		// countMap[selected]++;
		// if (ret == true) {
		// 	// debugRecord(selected - 2);
		// 	// debugRecord(selected - 1);
		// 	// debugRecord(selected);
		// 	return true;
		// }
	}

	//分开匹配 A-1,A,A + 1
	matched = true;
	if (v < 1 || v > 7) {
		matched = false;
	} else {
		for (var i = 0; i < 3; ++i) {
			var t = selected - 1 + i;
			var cc = countMap[t];
			if (cc == null) {
				matched = false;
				break;
			}
			if (cc == 0) {
				matched = false;
				break;
			}
		}
	}

	// 匹配成功，扣除相应数值，记录
	if (matched) {
		result.shunStrArr.push(`${selected - 1},${selected},${selected + 1}`);
		result.matchShun = true;
		// countMap[selected - 1]--;
		// countMap[selected]--;
		// countMap[selected + 1]--;
		// var ret = checkSingle(seatData);
		// countMap[selected - 1]++;
		// countMap[selected]++;
		// countMap[selected + 1]++;
		// if (ret == true) {
		// 	// debugRecord(selected - 1);
		// 	// debugRecord(selected);
		// 	// debugRecord(selected + 1);
		// 	return true;
		// }
	}

	// 分开匹配 A,A+1,A + 2
	matched = true;
	if (v > 6) {
		matched = false;
	} else {
		for (var i = 0; i < 3; ++i) {
			var t = selected + i;
			var cc = countMap[t];
			if (cc == null) {
				matched = false;
				break;
			}
			if (cc == 0) {
				matched = false;
				break;
			}
		}
	}

	// 匹配成功，扣除相应数值，记录
	if (matched) {
		result.shunStrArr.push(`${selected},${selected + 1},${selected + 2}`);
		result.matchShun = true;
		// countMap[selected]--;
		// countMap[selected + 1]--;
		// countMap[selected + 2]--;
		// var ret = checkSingle(seatData);
		// countMap[selected]++;
		// countMap[selected + 1]++;
		// countMap[selected + 2]++;
		// if (ret == true) {
		// 	// debugRecord(selected);
		// 	// debugRecord(selected + 1);
		// 	// debugRecord(selected + 2);
		// 	return true;
		// }
	}
	return result;
}
exports.matchShun = matchShun;

// 单牌，判断顺子
function checkShun(paiArr) {
	console.log('check shun', paiArr);
	let shunArr = [];
	let danArr = [];
	let shunDict = {};

	let _countMap = {};
	let match = false;
	paiArr.forEach(e => {
		_countMap[e] = 1;
	});
	for (let inx = 0; inx < paiArr.length; inx++) {
		const el = paiArr[inx];
		const res = matchShun({
			holds: paiArr,
			countMap: _countMap,
		}, el);
		console.log(res);
		if (res.matchShun) {
			match = res.matchShun;
			res.shunStrArr.map(e => {
				if (shunDict[e]) {
					shunDict[e]++;
				} else {
					shunDict[e];
				}
			});
		} else {
			danArr.push(el);
		}
		// const next = paiArr[inx + 1] || undefined;
		// const nextT = paiArr[inx + 2] || undefined;
		// // 从小到大，判断连续牌
		// // 非9tong，tiao，wan
		// if (el < (9 - 2) || el < (18 - 2) || el < (27 - 2)) {
		// 	if (next && nextT && next == el + 1 && nextT == el + 2) {
		// 		shunArr.push(el);
		// 	} else {
		// 		danArr.push(el);
		// 		continue;
		// 	}
		// } else {
		// 	danArr.push(el);
		// }
	}
	shunArr = Object.keys(shunDict);
	return {
		shunArr,
		shunDict,
		danArr,
		match
	};
}
// 会牌判定
function checkHuiCanHu(obj) {
	let returns = {
		kanArr: [],
		canhu: false,
	};
	let result = {};
	let huArr = [];
	const { numHuiPai, duimap, danmap, huipai } = obj;

	if (numHuiPai == 1) {
		// 单张会
		if (duimap.length > 0) {
			// 有眼
			if (duimap.length == 1) {
				// 只有一对，只能做眼，判断能否补充顺，补充顺的可能
				// -2，-1，0/-1，0，1/0，1，2
				result = checkShun(danmap);
				// 必须只差一张，且是连续的
				if (result.danArr.length == 2 &&
					(result.danArr[0] + 1 == result.danArr[1] ||
						result.danArr[0] + 2 == result.danArr[1])
				) {
					// let one = checkShun(result.danArr.push(huipai))
					// if (one.matchShun) {
					// }
					res.canhu = true;
					res.kanArr = result.shunArr;
				}
			} else {
				// 多个对，判断peng，必须没有空dan，且dui只有两对，hu牌选其中一对
				result = checkShun(danmap);
				if (result.danArr.length == 0 && duimap.length == 2) {
					res.canhu = true;
					res.kanArr = duimap;
				} else {
					// // 否则，全部都是对，对对胡
					// if (duimap.length == 6 && danmap.length == 1) {
					// 	// canhu = true;
					// }
				}
			}
		} else {
			// 无眼，会牌必须组眼，判断剩余牌是否顺，分离顺，得可会的dan
			result = checkShun(danmap);
			// 剩余单牌多于1张，则不能hu
			if (result.danArr.length == 1) {
				// canhu = true;
				res.canhu = true;
				res.kanArr = result.shunArr;
			}
		}

	} else if (numHuiPai == 2) {
		// 两张会
		if (duimap.length > 0) {
			let _sign = 0;
			if (duimap.length == 1) {
				// 只有一对，要么组碰，要么组眼
				result = checkShun(danmap);
				if (result.shunArr.length == 0 && result.danArr.length < 5) {
					// 没有顺，则判断，超5张里有两张会肯定不能胡
					// 判断有没有连续
					for (let i = result.danArr.length - 1; i < result.danArr.length; i--) {
						const el = result.danArr[i];
						if (el - 1 == result.danArr[i - 1] || el - 2 == result.danArr[i - 2]) {
							_sign++;
						}
					}
					if (_sign > numHuiPai && _sign < 2 * numHuiPai) {
						res.canhu = true;
						res.kanArr = result.danArr;
					}
				} else if (result.danArr.length <= 5) {
					// 单排是否连续
					for (let i = result.danArr.length - 1; i < result.danArr.length; i--) {
						const el = result.danArr[i];
						if (el - 1 == result.danArr[i - 1] || el - 2 == result.danArr[i - 2]) {
							_sign++;
						}
					}
					if (_sign > numHuiPai && _sign < 2 * numHuiPai) {
						res.canhu = true;
						res.kanArr = result.danArr;
					}
				}
			} else {
				// 多对
				// 判断有没有顺，没有顺，则应该都是对，满足2张会牌则判断hu
				result = checkShun(danmap);
				// 3对会两张可以胡
				if (result.danArr.length == 0 && result.shunArr.length == 0 && duimap.length == 3) {
					res.canhu = true;
					res.kanArr = duimap;
				}
				// 2对会两张，则对要一张，另一张补充给顺
				if (duimap.length == 2 && (result.danArr.length == 2 && (result.danArr[0] + 1 == result.danArr[1]) || result.danArr[0] + 2 == result.danArr[2])) {
					res.canhu = true;
					res.kanArr = [...duimap, result.danArr];
				}

			}
		} else {
			// 两会，全单张，必须组眼，则另一张会要组顺
			result = checkShun(danmap);
			// if (result.shunArr.length > 0) {
			// } else {
			// 	// 无顺子单牌
			// }
			// 找连续
			for (let i = result.danArr.length - 1; i < result.danArr.length; i--) {
				const el = result.danArr[i];
				if (el - 1 != result.danArr[i - 1] && el - 2 != result.danArr[i - 2]) {
					continue;
				} else {
					res.canhu = true;
					res.kanArr = result.danArr;
				}
			}

		}

	} else if (numHuiPai == 3) {
		// 三张会

	} else if (numHuiPai == 4) {
		// 四张会

	} else {

	}

	return returns;
}
/*
console.log(Date.now());
//检查筒子
checkTingPai(seatData,0,9);
//检查条子
checkTingPai(seatData,9,18);
//检查万字
checkTingPai(seatData,18,27);
console.log(Date.now());

for(k in seatData.tingMap){
	console.log(nameMap[k]);	
}
*/
exports.checkTingPai = checkTingPai;
// 真实会牌
// 0-8 9-17 18-26 27-29 30 33
exports.getRealHuipai = function (pai) {
	if (!pai) {
		return null
	}
	let real = null;
	if (pai == 8) {
		real = 0;
	} else if (pai == 17) {
		real = 9;
	} else if (pai == 26) {
		real = 18;
	} else if (pai == 29) {
		real = 27;
	} else if (pai == 33) {
		real = 30;
	} else {
		real = pai + 1;
	}

	return real;
}

exports.checkTingHuiPai = function (game, seatData, pai) {
	const { huipai, realhuipai } = game;
	const { holds, countMap } = seatData;
	let canhu = false;
	let teshugangs = null;
	// const begin = 0;
	// const end = 26;
	// let numHuiPai = 0;
	// const { pengs, angangs, diangangs, wangangs, teshugangs } = seatData;
	// if (seatData.countMap[huipai] < 1) {
	// 	// 没会牌，不验证胡
	// 	return false;
	// }
	// // 先清掉会牌
	// numHuiPai = seatData.countMap[huipai];
	// seatData.countMap[huipai] = 0;
	// // hu count
	// let pengmap = [];
	// let gangmap = [];
	// let duimap = []; // 对牌
	// let danmap = []; // 单牌
	// for (var k in seatData.countMap) {
	// 	k = parseInt(k);
	// 	var c = seatData.countMap[k];
	// 	if (k > end) {
	// 		break;
	// 	}
	// 	if (c == 3) {
	// 		// peng
	// 		pengmap.push(k);
	// 	} else if (c == 4) {
	// 		// 手上有4张牌，则判断拆成peng和dan
	// 		pengmap.push(k);
	// 		danmap.push(k);
	// 	} else if (c == 2) {
	// 		duimap.push(k);
	// 	} else if (c == 1) {
	// 		danmap.push(k);
	// 	}
	// }
	// pengs.forEach(peng => {
	// 	pengmap.push(peng);
	// });
	// [...diangangs, ...angangs, ...wangangs, ...teshugangs].forEach(g => {
	// 	gangmap.push(g);
	// });

	// // 会牌补回来
	// seatData.countMap[huipai] = numHuiPai;

	// let result = {}; // 匹配后
	// danmap.sort((a, b) => a - b);
	// duimap.sort((a, b) => a - b);
	// console.log('can huipai hu', huipai, duimap, danmap);
	// // 判断是否组成胡牌
	// result = checkHuiCanHu({
	// 	huipai,
	// 	danmap,
	// 	duimap,
	// 	numHuiPai,
	// });
	// canhu = result.canhu;
	// console.log('can hu', canhu, result);

	// 去掉手上的会牌，手牌不能是中发白东南西北，以免影响判断顺
	let cards = holds.filter(e => e != realhuipai); //  && e < 30 // 超30则特殊处理，不做顺

	console.log(cards,'--------检查手牌-----');
	console.log('---------手上会牌---------', realhuipai, countMap[realhuipai]);
	canhu = canHuLaizi(cards, countMap[realhuipai]); // 普通胡检查
	// 如果普通牌的会牌胡都失败，则检查特殊杠胡
	// 中发白东南西北与会牌
	// e >= 30 || 
	let teshu_cards = cards.filter(e => e != realhuipai && (e == 0 || e == 8 || e == 9 || e == 17 || e == 18 || e == 26));
	console.log('带有特殊杠的数组---------', teshu_cards);
	if (!canhu && teshu_cards.length) {
		const objs = canHuTeshu(cards, teshu_cards, countMap[realhuipai]);
		canhu = objs.canhu;
		teshugangs = objs.teshugangs;
	}

	return { canhu, teshugangs };
}
function shunArrFn(arr, pai) {
	var result = [];
	// result[i] = [arr[0]];
	// arr.reduce(function (prev, cur) {
	// 	cur - prev === 1 ? result[i].push(cur) : result[++i] = [cur];
	// 	return cur;
	// });
	// 中发白东南西北没顺
	if (pai > 26) {
		return result;
	}
	// 排序方便判断
	arr.sort((a, b) => Number(a) - Number(b))
	let rules = ['-2,-1,0', '-1,0,1', '0,1,2'];
	rules.map(e => {
		let r = e.split(',').map(e => +e);
		let su = r.filter(m => {
			let p = m + pai;
			// console.log(`吃牌: ${m}，${p}，inx: ${arr.indexOf(p) > -1}`);
			if (p % 9 > 0 && p % 9 < 9 && arr.indexOf(p) > -1) {
				return true;
			} else {
				return false;
			}
		});
		console.log('---看看过滤后的牌：---', su);
		if (su.length == 3) {
			result.push(su.map(e => +e + pai).join(','))
		}
	});

	return result;
}
exports.shunArrFn = shunArrFn;
/**
 * 判断顺碰
 */
const isShunKe = function (cards, laiziCount, shunOrKe) {
	if (cards.length === 0) {
		return true;
	}
	// 非单独碰
	if (shunOrKe !== 'ke') {
		// 若第一张是顺子中的一张  
		for (var first = cards[0] - 2; first <= cards[0]; first++) {
			if (cards[0] > 30) { // 东南西北不判断顺
				continue;
			}
			if (first < 0 || first % 9 > 6 || (laiziCount === 0 && first < cards[0])) {
				// 顺子第一张牌不会大于7点、无赖子情况下顺子第一张只能用手上的牌  
				continue;
			}
			var shunCount = 0;
			for (var i = 0; i < 3; i++) {
				if (cards.indexOf(first + i) >= 0) {
					shunCount++;
				}
			}
			if (shunCount === 3 || shunCount + laiziCount >= 3) {
				// 找到包含第一张牌的顺子  
				var puCards = cards.slice();
				var puLaizi = laiziCount;
				for (var i = 0; i < 3; i++) {
					var deletePos = puCards.indexOf(first + i);
					if (deletePos >= 0) {
						puCards.splice(deletePos, 1);
					}
					else {
						puLaizi--;
					}
				}
				if (isShunKe(puCards, puLaizi)) {
					// 剩下的牌成扑  
					return true;
				}
			}
		}
		// 单独顺
		if (shunOrKe === 'shun') {
			return false;
		}
	}
	// 若第一张是刻子中的一张  
	var keziCount = 1;
	var keziCard = cards[0];
	if (cards[1] === keziCard) {
		keziCount++;
	}
	if (cards[2] === keziCard) {
		keziCount++;
	}
	if (keziCount === 3 || keziCount + laiziCount >= 3) {
		var puCards = cards.slice();
		var puLaizi = laiziCount;
		for (var i = 0; i < 3; i++) {
			var deletePos = puCards.indexOf(keziCard);
			if (deletePos >= 0) {
				puCards.splice(deletePos, 1);
			}
			else {
				puLaizi--;
			}
		}
		if (isShunKe(puCards, puLaizi)) {
			return true;
		}
	}
	return false;
}
exports.isShunKe = isShunKe;
/**
 * 判断胡牌
 * @param {*} id 
 * @returns 
 */
const canHuLaizi = function (cards, laiziCount) {
	if ((cards.length + laiziCount + 1) % 3 != 0) {
		// 若牌张数不是2、5、8、11、14则不能胡  
		return false;
	}
	// 排序方便胡牌判断  
	cards.sort(function (a, b) {
		return a - b;
	})
	// 依次删除一对牌做将，其余牌全部成扑则可胡  
	for (var i = 0; i < cards.length; i++) {
		if (i > 0 && cards[i] == cards[i - 1]) {
			// 和上一次是同样的牌，避免重复计算  
			continue;
		}
		if ((i + 1 < cards.length && cards[i] == cards[i + 1]) || laiziCount > 0) {
			// 找到对子、或是用一张癞子拼出的对子  
			var puCards = cards.slice();
			var puLaizi = laiziCount;
			puCards.splice(i, 1);
			if (puCards[i] == cards[i]) {
				puCards.splice(i, 1);
			}
			else {
				puLaizi--;
			}
			// 删去对子判断剩下的牌是否成扑  
			// console.log('--------检验是否成扑的牌--------', puCards, puLaizi);
			if (isShunKe(puCards, puLaizi)) {
				return true;
			}
		}
	}
	if (laiziCount >= 2 && isShunKe(cards, laiziCount - 2)) {
		// 两个癞子做将牌特殊判定处理  
		return true;
	}
	return false;
}
exports.canHuLaizi = canHuLaizi;

// 特殊杠胡，teshu cards 包含了特殊杠牌的组
const canHuTeshu = function (cards, teshu_cards, laiziCount) {
	var canhu = false;
	var teshu_arr = [
		// [30,31,32,33], // 会牌不能变这个，因为会超14张
        // [27,28,29], // 其实普通判断的时候就已经做过这个判断了
        [0,9,18],
        [8,17,26],
	]
	let lenHui = laiziCount;
	var teshu_res = {}
	// 排序方便胡牌判断  
	cards.sort(function (a, b) {
		return a - b;
	})
	teshu_cards.sort(function (a, b) {
		return a - b;
	});
	console.log('---验证会牌特殊杠的胡---', lenHui, cards, teshu_cards);
	// 抽离匹配特殊杠与会牌的组合，剩下的再做普通胡牌匹配
	for (let i = 0; i < teshu_arr.length; i++) {
		const each_arr = teshu_arr[i];
		teshu_res[each_arr.join(',')] = 0;

		const filter_arr = each_arr.filter(e => teshu_cards.includes(e));
		console.log(filter_arr, '--------检验特殊杠会牌-----');
		// 特殊杠的长度与手牌现有的特殊杠牌长度加上会牌长度相等则匹配
		if (filter_arr.length > 0 && each_arr.length <= filter_arr.length + lenHui) {
			teshu_res[each_arr.join(',')] = 1;
			lenHui -= each_arr.length - filter_arr.length;
			continue;
		}
		
		// const filter_arr = cards.filter(e => each_arr.includes(e));
		// let filter_dict = {};
		// filter_arr.forEach(e => {
		// 	if (filter_dict[e]) {
		// 		filter_dict[e]++;
		// 	} else {
		// 		filter_dict[e] = 1;
		// 	}
		// });
		// const res_arr = Object.keys(filter_dict).filter(e => {
		// 	if (filter_dict[e] >= 2) {
		// 		filter_dict[e] -= 2;
		// 	}
		// 	return filter_dict[e] > 0;
		// });
		// console.log(filter_arr, filter_dict, res_arr);
		// teshu_res[each_arr.join(',')] = res_arr.length;
		// // 特殊杠长度能匹配上，则匹配标记
		// if (each_arr.length == res_arr.length) {
		// 	continue;
		// }
		// // 特殊杠的长度与手牌现有的特殊杠牌长度加上会牌长度相等则可以胡
		// if (each_arr.length == res_arr.length + laiziCount) {
		// 	canhu = true;
		// 	break;
		// }
	}
	console.log('过滤一遍-----', teshu_res);
	let teshugangs = [];
	// let cards_res = cards.slice();
	// let teshugangs = Object.keys(teshu_res).filter(e => teshu_res[e] > 0)
	// teshugangs.forEach(e => {
	// 	let arr = e.split(',').map(e => +e);
	// 	arr.forEach(item => {
	// 		let inx = cards_res.indexOf(item);
	// 		if (inx > -1) {
	// 			cards_res.splice(cards_res.indexOf(item), 1);
	// 		}
	// 	})
	// })
	// console.log('去掉特殊杠', cards_res, cards, teshugangs);
	// // 没有匹配特殊杠，则检查对
	// // if (!canhu) {
	// // 	Object.keys(teshu_res).forEach(e => {
	// // 		const teshu_val = teshu_res[e];
	// // 		const len = e.split(',').length;
	// // 		if (teshu_val > 0 && teshu_val < len) {
	// // 		}
	// // 	})
	// // }
	// canhu = canHuLaizi(cards_res, lenHui);

	return { canhu, teshugangs };
}

/**
 * 杠小分计算 
 * @param gangs (angangs, diangangs, wangangs, teshugangs) 杠牌数据
 * @param isAnGang 是否是暗杠数据
 * 例: calcAnGangFen(seatData.diangangs, false)
 */
exports.calcGangFen = function (gangs, isAnGang, game) {
    // 这里看下中发白的暗杠 服务端是怎么存储的
	var teshu_dict = {
		"30,31,32,33": 4,
        "27,28,29": 4,
        "0,9,18": 4,
        "8,17,26": 4,
	}
    var totalScore = 0; // 总分
    for (var i = 0; i < gangs.length; i ++) {
        // 会牌 改成服务端会牌字段
        var huipai = game.realhuipai;
		// 幺 九 杠 以及中发白
		if (typeof gangs[i] === 'string') {
			var pai_arr = gangs[i].split(',').map(e => +e);
			var teshu_key = Array.from(new Set(pai_arr)).join(',');
			if (teshu_dict[teshu_key]) {
				totalScore += teshu_dict[teshu_key];
			}
		} else {
			var pai = gangs[i];
			// 会杠
			if (pai == huipai) {
				totalScore += 16;
			// 二 八杠 2筒 8万
			} else if (pai == 1 || pai == 10 || pai == 19 || pai == 7 || pai == 16 || pai == 25) {
				totalScore += 8;
			// 幺 九 杠 以及中发白 这里就当中发白杠 只推进数组其中一张牌
			// } else if (pai == 0 || pai == 9 || pai == 18 || pai == 8 || pai == 17 || pai == 26 || (pai <= 29 && pai >= 27)) {
			// 	totalScore += 4;
			} else {
				totalScore += 2;
			}
		}
    }
    return isAnGang ? totalScore : totalScore / 2;
}

exports.getMJType = function (id) {
	if (id >= 0 && id < 9) {
		//筒
		return 0;
	} else if (id >= 9 && id < 18) {
		//条
		return 1;
	} else if (id >= 18 && id < 27) {
		//万
		return 2;
	} else if (id >= 27 && id < 34) {
		// 四风、中发白
		return 3;
	} else {
		return -1;
	}
}

exports.shuffle = function (game) {
	var mahjongs = game.mahjongs;

	//筒 (0 ~ 8 表示筒子
	var count = 0;
	for (var i = 0; i < 9; ++i) {
		for (var c = 0; c < 4; ++c) {
			mahjongs[count] = i;
			count++;
		}
	}

	//条 9 ~ 17表示条子
	for (var i = 9; i < 18; ++i) {
		for (var c = 0; c < 4; ++c) {
			mahjongs[count] = i;
			count++;
		}
	}

	//万 18 ~ 26表示万
	for (var i = 18; i < 27; ++i) {
		for (var c = 0; c < 4; ++c) {
			mahjongs[count] = i;
			count++;
		}
	}

	// 中27 发28 白29 东30 南31 西32 北33 
	for (var i = 27; i < 34; i++) {
		for (var c = 0; c < 4; ++c) {
			mahjongs[count] = i;
			count++;
		}
	}

	// for (var i = 0; i < count; ++i) {
	for (var i = 0; i < mahjongs.length; ++i) {
		var lastIndex = mahjongs.length - 1 - i;
		var index = Math.floor(Math.random() * lastIndex);
		var t = mahjongs[index];
		mahjongs[index] = mahjongs[lastIndex];
		mahjongs[lastIndex] = t;
	}
	console.log('mahjongs and length', mahjongs, mahjongs.length);
}

// exports.playFlyEgg = function (seatData) {
// 	// console.log(seatData, 'play fly egg');
// 	let isJi = false
// 	//筒 (0 ~ 8 表示筒子
// 	//条 9 ~ 17表示条子
// 	//万 18 ~ 26表示万
// 	// 中27 发28 白29 东30 南31 西32 北33
// 	let egg_keys = {
// 		0: 'yitong',
// 		8: 'jiutong',
// 		9: 'yaoji', // 幺鸡
// 		17: 'jiutiao',
// 		18: 'yiwan',
// 		26: 'jiuwan',
// 		27: 'zhong',
// 		28: 'fa',
// 		29: 'bai',
// 		30: 'dong',
// 		31: 'nan',
// 		32: 'xi',
// 		33: 'bei'
// 	}
// 	let need_arr = Object.keys(egg_keys);
// 	let get_includes = (arr1, arr2) => {
// 		let temp = [];
// 		for (const item of arr2) {
// 			arr1.find(i => i === item) ? temp.push(item) : '';
// 		}
// 		return templ
// 	}
// 	// 遍历玩家
// 	// for (let inx = 0; inx < game.gameSeats.length; inx++) {
// 	// 	const el = game.gameSeats[inx];
// 	// 	const holds = el.holds;
// 	// 	console.log(holds, 'holds begin');
// 	// 	holds.inclu
// 	// }
// 	const holds = seatData.holds
// 	console.log('egg holds ', holds);
// 	let res_arr = get_includes(holds, need_arr);
// 	if (res_arr.length > 0) {
// 		isJi = true
// 	}

// 	var result = {
// 		// game,
// 		// seatData,
// 		gangArr: res_arr,
// 		isJi
// 	}

// 	// return JSON.stringify(result);
// 	return result;
// }

// 小鸡玩法
exports.xiaojiDict = function () {
	const teshuArr = ['0,9,18', '8,17,26', '27,28,29', '30,31,32,33'];
	const teshuStr = teshuArr.join(',');

	return {
		pai: 9, // 幺鸡
		canChange: teshuStr.split(',').map(e => +e), // 只对teshu杠有效
		canUseCase: teshuArr, // 有效牌型
	};
}

exports.checkXiaoJi = function (seatData, countMap) {
	const { pai, canChange, canUseCase } = exports.xiaojiDict();
	// console.log(holds, 'xiao ji holds');
	console.log('----进入小鸡验证----', countMap, '----小鸡牌----', pai);
	// 根据手牌判断有多少xiaoji以及其他判定
	// const len = holds.filter(e => e == pai).length || 0;
	const len = countMap[pai] || 0;
	let caseCountMap = {}
	let caseCanGang = {}
	if (len > 0) {
		for (let i = 0; i < canUseCase.length; i++) {
			const el = canUseCase[i];
			let lenSum = 0;
			caseCountMap[el] = { canGang: false };
			// const elArr = el.split(',').map(e => {
			// 	const num = e * 1;
			// 	const numHolds = holds.filter(e => num == e);

			// 	caseCountMap[el][num] = numHolds.length;
			// 	if (numHolds.length == 0) {
			// 		caseCountMap[el][pai] = len; // 记录当前牌
			// 	}
			// 	return num;
			// });
			// // 判断此case够不够形成杠，够则组合并标记
			// // caseCountMap[el]
			// let sarr = Object.keys(caseCountMap[el]).filter(k => {
			// 	if (countMap[k] >= caseCountMap[el][k]) {
			// 		return k;
			// 	} else if (caseCountMap[el][pai] >= countMap[k]) {
			// 		return k;
			// 	}
			// });
			// console.log(sarr);
			// if (sarr.length > 0) {
			// 	caseCanGang[el] = {
			// 		countMap: caseCountMap[el],
			// 		canPeng: sarr,
			// 	}
			// }

			el.split(',').forEach(e => {
				// console.log(+e, '-----小鸡匹配中-----', countMap[e], pai);
				if (+e != pai) {
					caseCountMap[el][e] = countMap[e] || 0;
					if (countMap[e] > 0) {
						lenSum += 1;
					}
					console.log('------小鸡玩法记录-----', e, countMap[e], '---长度---', lenSum, lenSum + len, el.split(',').length);
				}
			});
			// 判断此case够不够形成杠，够则组合并标记
			if (lenSum + len >= el.split(',').length) {
				caseCountMap[el].canGang = true;
				caseCountMap[el]['9'] = len;
			}
		}
		console.log('--------caseCountMap-------', caseCountMap);
	}
	return {
		pai,
		len,
		caseCountMap,
	};
}
